The Nintendo 64 Gameshark Code Injector v4.3

by Triclon

E-mail - triclon@gmail.com
Website - https://triclon.neocities.org

This utility will inject Gameshark codes directly into most Nintendo 64 roms.  It is console compatible with a flashcart and works in most emulators.  Right after a game boots, the injector will run and copy the code handler, which runs through all the active codes continuously, into the Expansion Pak RAM.  The code handler hooks into the game's exception handler and will run continuously, applying active codes.  It will also run any F0 or F1 type codes at boot.  Unlike a real Gameshark, which is limited to a few hundred lines of code, this injector allows you to inject nearly unlimited lines of Gameshark codes.  


~~~ Requirements ~~~

-Python 3 to run the injector
-The following python libraries (you probably already have them installed with python): tkinter, yaml
-A Nintendo 64 ROM to patch
-An Expansion Pak and flash drive to play on console


~~~ Get Gameshark codes ~~~

I highly recommend http://gamehacking.org, the primer archive of cheat codes on the internet.  You can export them in a variety of formats.  The injector can read in the plain text, .yml, and .cht files outputted by http://gamehacking.org.


~~~ Using the GUI to patch Gameshark codes into a ROM ~~~

Open a terminal and go to the directory where the injector is stored and type the following

python injector.py

It should open the GUI.

To load a ROM, click the Load ROM button on the top left.  Select the rom you want to patch.  It must be big endian, which means it should have the extension .z64.  If it is little endian and/or has the extension .n64 you probably need to byte swap it first.  

You can type or paste in gameshark codes in the text box where it says "Paste Gameshark codes here".  The lines of code should look like the following format:

800798E7 0011
8102E154 2400
8102CA08 2400

Extra text above, below, or after the codes such as code names, descriptions, or comments are perfectly fine.  The injector will ignore extra comments.

You can also load codes by clicking the Load Codes button.  You can load in plain text files along with either the .cht or .yml files outputted by gamehacking.org (or possibly other things).

Clicking the Save Codes button will save the codes in the text box as a text file which you can load later.  Very useful for saving your favorite combinations of codes.

After loading the rom you want to patch and putting in the Gameshark codes you want, click the "Patch ROM" button to save your new patched rom.  The injector will append "_patched.z64" to the name of the rom but you can call it whatever you want.

IMPORTANT! If you are playing on a Wii emulator such as Wii64, Not64, or using virtual console inject, select the "Wii / old emulator" checkbox before patching your rom.  If you don't, your patched rom will not run on the Wii.  If you are you some other old emulator and your patched rom isn't working, selecting "Wii / old emulator" might fix the issue.  Note that roms patched with this setting on WILL NOT WORK ON THE ACTUAL N64 CONSOLE.  Make sure to deselect it if you want to run your patched roms on console.

Open your newly patched rom in your favorite emulator or copy to a flash drive for console and enjoy playing!


~~~ Using the command line interface (terminal) script to patch Gameshark codes into ROM ~~~~

You can also use the python script injector_cli.py to patch roms with Gameshark codes from the command line.   Besides being called from the command line, the functionality of this script is identical to the GUI.  Store your codes in a text file and then run the script as shown in the example below.  

python injector_cli.py gameshark_code_text_file.txt rom.z64 rom_patched.z64

1st argument is the path to the gameshark code text file
2nd argument is the path to the rom you want to patch
3rd argument is the path to save the patched rom. 


~~~ Converting MIPS assembly into Gameshark codes ~~~~

There is a script that can convert MIPS assembly into Gameshark codes.  You can then use the GS code injector to inject these codes into a rom.

You run the script from the command line like so.

python asm_to_gameshark.py assembly_code.txt 0x80123458 output_gameshark_code.txt

1st argument is a text file with the assembly code
2nd argument is where in RAM you want the gameshark code to start
3rd argument is where to output the text file containing the gameshark codes

The assembly code in the text file should be written pretty standard, look something like 

addiu $a1, $a1, 0x0001
nop

Each instruction should be on its own line and use spaces or commas to separate the different parts of the instruction.  Using parentheses is fine.

~~~ Supported Gameshark code types ~~~

The N64 Gameshark Code Injector supports the following code types:

80, 81, D0, D1, D2, D3, F0, F1, A0, A1, FF, EE, DE

This covers nearly all code types for the Gameshark.

~~~ Troubleshooting ~~~

If your game does not boot, check the following
-If your file has the extension .n64, that means it is little-endian and you need to byte swap it.  All roms must be .z64 files and be big-endian.  The online byte swapper on hack64.net can do it: https://hack64.net/tools/swapper.php  
-On emulator: Make sure the expansion pak (8 MB) is enabled.  Enable Interpreter Mode, or disabled "DynaRec" or Dynamic Recompiling modes of your emulator.  In Project 64, you might also need to turn off Enhancements, if the above solutions didn't work.  If you are still having trouble, you can try patching your rom with the "Wii / Old emulator" checkbox selected.
-On console: You will need the Expansion Pak (for the most part, see "Advanced Stuff" below for a possible workaround)
-If the injector gives you the error "ERROR: No exception handler found!" your rom is not compatible with the Gameshark Code Injector.  This is because not every rom boots the same way.  Please contact me with information about the rom you are trying to patch, and I will try to see if I can hardcode a solution.
-Sometimes if a game won't boot or Gameshark codes not work, be sure you are you using the proper enable/master codes.  These will be F0, F1, EE, FF, and/or DE type codes.  Be sure to include them.
-If the game uses the expansion pak and there is an enable code that looks like F0000319 0078 and it does not boot, you might also need to add the following additional enable code: FF780000 0000.

If you are still having trouble contact me: triclon@gmail.com


~~~ Wondering how Gameshark codes work? ~~~`
 
Check out the following links:

EnHacklopedia - http://www.bsfree.org/hack/hacking_n64.html
The Secrets of Processional Gameshark Hacking - http://viper.shadowflareindustries.com/?file=hackv500c.html&cat=hax0r


~~~ Advanced Stuff ~~~

-Making compatible without the expansion pak
For the most part, this Gameshark Code Injector uses the Expansion Pak RAM starting at 0x80500000 to store the active codes when the game is running.  However, it is possible to get it to run on console with just the Jumper Pak.  First you need to find a location in the RAM the game does not use.  You can search around with something like the Project 64 debugger memory viewer, or even a Gameshark's own memory viewer.  Be aware that you also must have sufficient space in ram to store the number of Gameshark codes you wish to inject.  Once you are sure you have found an area of RAM  you are confident the game will never use, you want to point to at the beginning of that location with an FF type enable code.  I will use the enable code FFXXXXXX 0000 where XXXXXX is the last 6 digits of the where in the ram I want to put my code handler.  For example, if my game does not use the last 1 kb of ram between 0x803FF000 and 0x80400000, I will include the enable code FF3FF000 0000.

-Limitations on the number of codes and reducing lag
The N64 Gameshark Code Injector allows a nearly unlimited amount of Gameshark codes to be injected into a rom.  There are a few limitations to this.  First is the amount of RAM available.  With each GS code taking up 3-4 bytes of memory, you could theoretically inject over 1 million GS codes into the 4 MB of Expansion Pak RAM.  Stress testing shows that over 25,000 lines of GS code starts to cause a game to lag on console.  Over 100,000 GS codes will lag the game enough to make it unplayable.  This probably is not so much of a problem for emulators.  The Code Injector will try to optimize 16 bit codes that are next to each other in ram that form 32 bit words (e.g. MIPS assembly type codes) to reduce the code handler size and lag.

-Arbitrary code injection-
F0 and F1 type Gameshark codes are run only at boot and directly from the ROM.  This means you can theoretically inject as many F0 and F1 type codes as you want with no RAM or lag limitations.  Oftentimes 80, 81, A0, or A1 type codes can be converted to F0 or F1 type codes.  If any of these codes are derived from MIPS assembly, you can probably simply replace the 8 or A with an F and it would work fine.   You can use the script to convert assembly to gameshark code to, described above.  It is feasible that large ram hacks can be injected in this way.   Future versions might allow directly assembly injection, if this feature is requested enough, turning the GS code injector into an asssembler.


Changelog
-June 23, 2024 -v4.4 - Added compatibility for all versions of Turok.
-Feb 22, 2024 - v4.3 - Added command line interface and assembly to gameshark codes scripts.
-Jan 28, 2024 - v4.2 - Fixed bug that prevented FF type codes from working.  Added compatibility for Blast Corps (all versions) and F1 Racing Champions (EUR).
-Oct. 22, 2023 - v4.1 - Critical fix for v4.0 not loading roms.
-Oct. 6, 2023 - v4.0 - Major updates.  Injector is now a GUI!  Now can read and save gameshark codes.  Compatibility with Body Harvest (USA) and Blast Corps (USA).
-Dec. 17, 2022 - v3.3 - Major bug fixes. DE type enable codes should now work correctly and fixed a bug where a bad gameshark code, comment, or empty line in the gameshark codes list would cause all the subsequent codes to not get injected.
-Dec. 16, 2022 - v3.2 - Fixed compatibility issue with Goldeneye involving not all exception handler hooks being used. I put in checks for each hook.  Might also fix other games.
-Nov. 29, 2022 - v3.1 - Added compatibility with Shadows of the Empire (U) v1.0, v1.1, & v1.2.
-Nov. 27, 2022 - v3.0 - Added compatibility for Mario Tennis (USA) and Perfect Dark (USA) with hardcoded solutions.  Future versions will hopefully increase compatibility further.  Modified how the Gameshark Code Injector runs at boot to for increased compatibility and in-game performance.  Now you can add comments and blank lines to your gameshark codes and the injector will ignore them instead of crashing.
-Dec. 7, 2021 - v2.0 - Now supports almost every game and many more code types including F0, F1, A0, A1, FF, EE, and DE.
-Oct. 29, 2021 - Mario Golf version created.
-Jan 6, 2020 - v1.0 - Initial Release (MK64 version)


Acknowledgements:

This Gameshark Code Injector is based on my Mario Kart 64 Gameshark Code Injector, on the prompting of sdqfsdf and Fancy247 to create a way to use gameshark codes to import Gameboy characters into Mario Golf. I later expanded it to to be compatible with more games and code types.  It took me a long time to figuring out how to get all the pieces of this injector to work, so I hope you enjoy it.

Additional thanks to...
-DKO for porting Parasyte's n64crc program from c to python.  Originally based on uCON64's N64 checksum algorithm by Andreas Sterbenz.
-Viper187 and Parasyte for writing EnHacklopedia (see link later in readme) which was invaluable in helping me learn how the Gameshark actually works.
-Micro500 for snippets of python code that I borrowed from his Micro Mountain code to read/write N64 roms in python.
-Deadhamster for suggestions and moral support.
-Datel and Interact for creating the Nintendo 64 Gameshark/Action Replay
